package com.physics.mps.module.abaqus;

import com.physics.mps.entity.vo.TemperatureFieldVo;
import com.physics.mps.entity.vo.InteractionVo;
import com.physics.mps.entity.vo.OpenAbaqusFileVo;
import com.physics.mps.module.compute.AbstractComputeService;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.*;

/**
 * @author mcsoft
 * @since 2023/8/26
 */
@Deprecated
public class AbaqusComputeService extends AbstractComputeService {


    // ~ Variable & Constant
    // ========================================================================================================


    // ~ Public method
    // ========================================================================================================
    public OpenAbaqusFileVo generateComputePython(/**List<SimulationParam> paramList**/) throws IOException {
        String computePythonPath = "";
        String computePythonName = "";
        BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(new File(computePythonPath), true));
        StringBuilder sb = new StringBuilder();
        //1.导包
        sb.append("# -*- coding: mbcs -*-\n");
        sb.append("from abaqus import *\n");
        sb.append("from abaqusConstants import *\n");
        sb.append("from math import *\n");
        sb.append("from driverUtils import executeOnCaeStartup\n\n");

        //2.创建并保存cae文件，设置工作目录
        String caePath = "";
        String workDir = "";
        sb.append("Mdb()\n");
        sb.append("mdb.saveAs(pathName='" + caePath + "')\n");
        sb.append("import os\nos.chdir(r\"" + workDir + "\"");

        //3.导入stp文件
        String stpPath = "";
        bufferedWriter.write("step = mdb.openStep('" + stpPath + "', scaleFromFile=OFF)");
        sb.append("import os\nos.chdir(r\"" + workDir + "\"");
        sb.append("mdb.models['Model-1'].PartFromGeometryFile(name='model1', geometryFile=step, combine=False, dimensionality=THREE_D, type=DEFORMABLE_BODY)\n");

        //4.创建部件和材料，并把材料属性附到部件上
        Map<String, Map<String, String>> parts = new HashMap<>();
        int materialNum = 1;

        sb.append("a = mdb.models['Model-1'].rootAssembly\n");
        sb.append("a.DatumCsysByDefault(CARTESIAN)\n");

        for (Map.Entry<String, Map<String, String>> entry : parts.entrySet()) {
            String partName = entry.getKey();
            Map<String, String> material = entry.getValue();

            //4.1 选取部件
            sb.append(partName + " = mdb.models['Model-1'].parts['" + partName + "']\n");
            //4.2 创建材料
            String materialName = "Material-" + materialNum;
            sb.append("mdb.models['Model-1'].Material(name='" + materialName + "')\n");
            material.forEach((name, value) -> {
                sb.append("mdb.models['Model-1'].materials['" + materialName + "']." + name + "(table=((" + value + ", ), ))\n");
            });
            //4.3创建截面
            String sectionName = "Section-" + materialNum;
            sb.append("mdb.models['Model-1'].HomogeneousSolidSection(name='" + sectionName + "', material='" + materialName + "', thickness=None)\n");

            //4.4选择部件cells和根据坐标选cells
            String cellName = "cell" + materialNum;
            sb.append(cellName + " = " + partName + ".cells\n");
            String regionName = "region" + materialNum;
            sb.append(regionName + " = " + cellName + ".findAt(((" + 1 + ", " + 2 + ", " + 3 + "), ))\n");


            //4.5 赋予材料属性
            sb.append(partName + ".SectionAssignment(region=" + regionName + ", sectionName='" + regionName + "', offset=0.0, offsetType=MIDDLE_SURFACE, offsetField='', thicknessAssignment=FROM_SECTION)\n");

            //4.6 部件生成实例装配到a上
            String instanceName = partName;
            sb.append("a.Instance(name='" + instanceName + "', part=" + partName + ", dependent=ON)\n");

            materialNum++;
        }

        //5.创建分析步
        String timePeriod = "";
        String initialInc = "";
        String minInc = "";
        String maxInc = "";
        String delmx = "";

        sb.append("mdb.models['Model-1'].HeatTransferStep(name='Step-1', previous='Initial', timePeriod=" + timePeriod + ", initialInc=" + initialInc + ", minInc=" + minInc + ", maxInc=" + maxInc + ", deltmx=" + delmx + ")\n");

        //6.对流换热
        int interactionNum = 1;

        List<InteractionVo> interactions = new ArrayList<>();
        float sinkTemperature = 0;
        for (InteractionVo interaction : interactions) {
            String partName = interaction.getPartName();
            List<String[]> coordinates = interaction.getCoordinates();
            float filmCoeff = interaction.getFilmCoeff();

            sb.append("c" + interactionNum + " = " + "a.instances['" + partName + "'].cells\n");
            for (String[] coordinate : coordinates) {
                String x = coordinate[0], y = coordinate[1], z = coordinate[2];
                String regionName = "region" + interactionNum;
                sb.append(regionName + " = c" + interactionNum + ".findAt(((" + x + ", " + y + ", " + z + "), ))\n");
                String fieldName = "field" + interactionNum;
                sb.append("mdb.models['Model-1'].FilmCondition(name='Int-convecton', " +
                        "createStepName='Step-1', surface=" + regionName + ", definition=EMBEDDED_COEFF, " +
                        "filmCoeff=" + filmCoeff + ", filmCoeffAmplitude='', sinkTemperature=" + sinkTemperature + ", sinkAmplitude='', " +
                        "sinkDistributionType=UNIFORM, sinkFieldName='')\n");
                interactionNum++;
            }
        }

        //7.温度场
        int temperatureNum = 1;
        List<TemperatureFieldVo> fields = new ArrayList<>();
        for (TemperatureFieldVo field : fields) {
            String partName = field.getPartName();
            List<String[]> coordinates = field.getCoordinates();
            float temperature = field.getTemperature();

            sb.append("c" + temperatureNum + " = " + "a.instances['" + partName + "'].cells\n");
            for (String[] coordinate : coordinates) {
                String x = coordinate[0], y = coordinate[1], z = coordinate[2];
                String regionName = "region" + temperatureNum;
                sb.append(regionName + " = c" + temperatureNum + ".findAt(((" + x + ", " + y + ", " + z + "), ))\n");
                String fieldName = "field" + temperatureNum;
                sb.append("mdb.models['Model-1'].Temperature(name='field " + temperatureNum + "', " +
                        "createStepName='Initial', region=region, distributionType=UNIFORM, " +
                        "crossSectionDistribution=CONSTANT_THROUGH_THICKNESS, magnitudes=(" + temperature + ", ))\n");
                temperatureNum++;
            }
        }

        //8.网格
        Set<String> partNames = parts.keySet();
        float size = 0, deviationFactor = 0, minSizeFactor = 0;
        for (String partName : partNames) {
            sb.append("p = mdb.models['Model-1'].parts['" + partName + "']\n");
            sb.append("p.seedPart(size=" + size + ", deviationFactor=" + deviationFactor + ", minSizeFactor=" + minSizeFactor + ")\n");
            sb.append("c = p.cells\n");
            sb.append("len = len(c)\n");
            //掩码规律，体的数量为n，则选择所有体的掩码为2^n-1,转换为十六进制输入
            sb.append("i = 2 ** len - 1\n");
            sb.append("hexStr = hex(i)\n");
            sb.append("pickedRegions = c.getSequenceFromMask(mask=('[#hexStr ]', ), )\n");
            sb.append("p.generate()\n");
        }

        //9.Job
        String numCpus = "";
        String numDomains = "";
        String numGPUs = "";
        sb.append("mdb.Job(name='Job-1-tran', model='Model-1', description='', type=ANALYSIS,\n" +
                "    atTime=None, waitMinutes=0, waitHours=0, queue=None, memory=90,\n" +
                "    memoryUnits=PERCENTAGE, getMemoryFromAnalysis=True,\n" +
                "    explicitPrecision=SINGLE, nodalOutputPrecision=SINGLE, echoPrint=OFF,\n" +
                "    modelPrint=OFF, contactPrint=OFF, historyPrint=OFF, userSubroutine='',\n" +
                "    scratch='', resultsFormat=ODB, multiprocessingMode=DEFAULT, numCpus=" + numCpus + ",\n" +
                "    numDomains=" + numDomains + ", numGPUs=" + numGPUs + ")\n");
        sb.append("mdb.save()\n");
        sb.append("mdb.jobs['Job-1-tran'].submit(consistencyChecking=OFF)\n");
        sb.append("mdb.jobs['Job-1-tran'].waitForCompletion()\n");

        bufferedWriter.write(sb.toString());

        OpenAbaqusFileVo openAbaqusFileVo = new OpenAbaqusFileVo();
        return openAbaqusFileVo;
    }

    // ~ Override method
    // ========================================================================================================


    // ~ Private method
    // ========================================================================================================


    // ~ Autowired
    // ========================================================================================================


}